package sample;

import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import sample.Schedule;
import sample.Student;
import sample.Subject;

/**
 * @author Vo Minh Dat
 * @version 1.0
 * @since 2011-11-12
 */
public class XmlExport {

	/*
	 * Cac anh sua lai mot so duoi day cho phu hop:
	 * 	- DATE_FORMAT va TIME_FORMAT (Static Variables) anh sua format tuy y.
	 * 	- Khi Export Schedules khong hieu sao class nay khong ho tro lay ArrayList Schedule, nen tham so dau vao la List.
	 *  - Em khong biet thuc thi Java tren Windows the nao (va cung khong co du lieu de test)
	 *    nen co the code duoi day chua ok lam, anh test giup em va cho biet ket qua.
	 *  - Neu can, em co the lam luon phan nguoc (parse tu XML -> object).
	 */
	
	//========================================================================//
	// Static Variables
	//========================================================================//
	
	private static final DateFormat DATE_FORMAT = DateFormat.getDateInstance(DateFormat.SHORT);
	private static final DateFormat TIME_FORMAT = DateFormat.getTimeInstance(DateFormat.SHORT);
	
	//========================================================================//
	// Public Methods
	//========================================================================//
	
	public void exportSchedules(ArrayList<Schedule> obj, String path) throws ParserConfigurationException, TransformerFactoryConfigurationError, TransformerException {
		// ====Init new DOM==== //
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.newDocument();
		
		// ====Write to file====//
		writeXmlFile(generateSchedulesNode(obj, doc), path, doc);
	}
	
	public void exportSchedule(Schedule obj, String path) throws ParserConfigurationException, TransformerFactoryConfigurationError, TransformerException {
		// ====Init new DOM==== //
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.newDocument();
		
		// ====Write to file====//
		writeXmlFile(generateScheduleNode(obj, doc), path, doc);
	}
	
	public void exportStudent(Student obj, String path) throws ParserConfigurationException, TransformerFactoryConfigurationError, TransformerException {
		// ====Init new DOM==== //
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.newDocument();
		
		// ====Write to file====//
		writeXmlFile(generateStudentNode(obj, doc), path, doc);
	}
	
	public void exportSubject(Subject obj, String path) throws ParserConfigurationException, TransformerFactoryConfigurationError, TransformerException {
		// ====Init new DOM==== //
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.newDocument();
		
		// ====Write to file====//
		writeXmlFile(generateSubjectNode(obj, doc), path, doc);
	}
	
	//========================================================================//
	// Private Methods
	//========================================================================//
	
	private void writeXmlFile(Node rootNode, String path, Document doc) throws TransformerFactoryConfigurationError, TransformerException {
		// ====Write nodes==== //
		doc.appendChild(rootNode);

		// ====Write to file==== //
		Source source = new DOMSource(doc);
		File file = new File(path);
		Result result = new StreamResult(file);

		Transformer xformer = TransformerFactory.newInstance().newTransformer();
		xformer.transform(source, result);
	}
	
	private Node generateSchedulesNode(ArrayList<Schedule> schedules, Document document) {
		Node result = document.createElement("Schedules");
		
		for (int i = 0; i < schedules.size(); i++) {
			result.appendChild(generateScheduleNode(schedules.get(i), document));
		}
		
		return result;
	}
	
	private Node generateScheduleNode(Schedule schedule, Document document) {
		Node result = document.createElement("Schedule");
		
		// Student
		Node student = generateStudentNode(schedule.getStudent(), document);
		result.appendChild(student);
		
		// Subject
		Node subject = generateSubjectNode(schedule.getSubject(), document);
		result.appendChild(subject);
		
		// Misc. Info
		
		((Element)result).setAttribute("StartTime", TIME_FORMAT.format(schedule.getStartTime()));
		((Element)result).setAttribute("EndTime", TIME_FORMAT.format(schedule.getEndTime()));
		((Element)result).setAttribute("Room", schedule.getRoom());
		((Element)result).setAttribute("Seat", schedule.getSeat());
		((Element)result).setAttribute("ExamType", schedule.getExamType());
		((Element)result).setAttribute("Note", schedule.getNote());
		
		
		return result;
	}
	
	private Node generateStudentNode(Student student, Document document) {
		Node result = document.createElement("Student");
		
		Element eID = document.createElement("ID");
		eID.appendChild(document.createTextNode(student.getStID()));
		result.appendChild(eID);
		
		Element eName = document.createElement("Name");
		eName.appendChild(document.createTextNode(student.getStName()));
		result.appendChild(eName);
		
		Element eDOB = document.createElement("DOB");
		eDOB.appendChild(document.createTextNode(DATE_FORMAT.format(student.getStDOB())));
		result.appendChild(eDOB);
		
		return result;
	}
	
	private Node generateSubjectNode(Subject subject, Document document) {
		Node result = document.createElement("Subject");
		
		Element eID = document.createElement("SubName");
		eID.appendChild(document.createTextNode(subject.getFullSubName()));
		result.appendChild(eID);
		
		Element eName = document.createElement("FullSubName");
		eName.appendChild(document.createTextNode(subject.getFullSubName()));
		result.appendChild(eName);
		
		Element eDOB = document.createElement("Type");
		eDOB.appendChild(document.createTextNode(subject.getType()));
		result.appendChild(eDOB);
		
		return result;
	}
	
}
